﻿using System;
using System.Configuration;
using System.Data;
using System.Threading;
using MySql.Data.MySqlClient;

namespace Hx.Domain.Repositories.Dapper
{
    public class DapperRepositoryContext : IRepositoryContext
    {
        private readonly ThreadLocal<bool> _committed = new ThreadLocal<bool>(() => true);
        private readonly ThreadLocal<MySqlConnection> _connection;
        private readonly ThreadLocal<MySqlTransaction> _transaction;

        public MySqlConnection Connection
        {
            get { return _connection.Value; }
        }

        public MySqlTransaction Transaction
        {
            get { return _transaction.Value; }
        }

        public DapperRepositoryContext()
        {
            _connection = new ThreadLocal<MySqlConnection>(() => new MySqlConnection(ConfigurationManager.ConnectionStrings["HaoXue"].ConnectionString));
            _transaction = new ThreadLocal<MySqlTransaction>(() =>
            {
                if (_connection.Value.State != ConnectionState.Open)
                    _connection.Value.Open();

                return _connection.Value.BeginTransaction();
            });
        }

        public bool Committed
        {
            get { return _committed.Value; }
        }

        public void Commit()
        {
            _transaction.Value.Commit();
            _committed.Value = true;
        }

        public void Rollback()
        {
            _transaction.Value.Rollback();
            _committed.Value = false;
        }

        public void Dispose()
        {
            _transaction.Value.Dispose();
            _connection.Value.Close();
            _connection.Value.Dispose();
        }

        public Guid Id
        {
            get { return Guid.NewGuid(); }
        }

        public void Add<TAggregateRoot>(TAggregateRoot obj) where TAggregateRoot : class, IAggregateRoot
        {
            _connection.Value.Insert(obj, _transaction.Value);
            _committed.Value = false;
        }

        public void Modify<TAggregateRoot>(TAggregateRoot obj) where TAggregateRoot : class, IAggregateRoot
        {
            _connection.Value.Update(obj, new { obj.Id }, _transaction.Value);
            _committed.Value = false;
        }

        public void Delete<TAggregateRoot>(TAggregateRoot obj) where TAggregateRoot : class, IAggregateRoot
        {
            _connection.Value.Delete<TAggregateRoot>(new { obj.Id }, _transaction.Value);
            _committed.Value = false;
        }
    }
}